/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.homullus;

import java.awt.FlowLayout;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import javax.swing.JPanel;
import java.util.ArrayList;
import java.util.HashMap;
import javax.swing.JTextArea;
import org.homullus.SkeletonTransforms.PoseSkeleton;

/**
 *
 * @author Gary
 */
public class ControlPanel extends JPanel
{
    private Skeleton skeleton;
    public void setSkeleton(Skeleton s) { skeleton = s;
                                          initComponent();
                                          revalidate();}
    public Skeleton getSkeleton() { return skeleton; }

    private PoseAction action;
    private PoseControlHeading heading;
    private JTextArea poseTextArea;

    

    private ArrayList<PoseControl> poseControls;
    private HashMap<Bone, PoseControl> poseControlMapping;
    private PoseSkeleton poser = new PoseSkeleton();

    private String LastTextAreaValue = "";

    public ControlPanel()
    {
        initComponent();

        action = new PoseAction() {

            @Override
            public void ClickAction() {
                System.out.println("Action();");
                Pose pose = new Pose();
                PoseDirection rootPose = new PoseDirection();
                //rootPose.setChildPose(new ArrayList<PoseDirection>());
                if (skeleton.GetRoot().editable)
                {
                    rootPose = poseControlMapping.get(skeleton.GetRoot()).getPoseDirection();
                }
                pose.setRootPose(rootPose);
                Generate(pose.getRootPose(), skeleton.GetRoot());
                poseTextArea.setText(GenerateOutput());
                //poser.setPose(pose);
               // poser.Transform(skeleton);
                skeleton.setPose(pose);
            }
        };


    }


    private void Generate(PoseDirection p, Bone b)
    {
        if (b.childBones != null)
        {
            p.setChildPose(new ArrayList<PoseDirection>());
            for (int cb = 0; cb < b.childBones.size(); cb++)
            {
                GeneratePose(p, b.childBones.get(cb));
            }
        }
    }
    private void GeneratePose(PoseDirection p, Bone b)
    {
        PoseDirection direction = null;
        if (b.editable)
            direction = poseControlMapping.get(b).getPoseDirection();
        else
            direction = new PoseDirection();

        if (b.childBones != null)
        {

            direction.setChildPose(new ArrayList<PoseDirection>());
            for (int cb = 0; cb < b.childBones.size(); cb++)
            {
                GeneratePose(direction, b.childBones.get(cb));
            }
        }
        p.getChildPose().add(direction);
    }

    private void initComponent()
    {
        setLayout(new FlowLayout(FlowLayout.LEFT));
        if (skeleton != null)
        {
            poseControls = new ArrayList<PoseControl>();
            poseControlMapping = new HashMap<Bone, PoseControl>();
            heading = new PoseControlHeading();
            GenerateControls(skeleton.GetRoot());

            add(heading);
            for (int c = 0; c < poseControls.size(); c++)
            {
                add(poseControls.get(c));
            }

            poseTextArea = new JTextArea(11,20);
            poseTextArea.setWrapStyleWord(true);
            poseTextArea.addFocusListener(new FocusAdapter() {
                @Override
                public void focusGained(FocusEvent e) {
                    LastTextAreaValue = poseTextArea.getText();
                }
                @Override
                public void focusLost(FocusEvent e) {
                    UpdateTextArea();
                }
            });
            add(poseTextArea);

            Pose pose = new Pose();
            PoseDirection rootPose = new PoseDirection();
            //rootPose.setChildPose(new ArrayList<PoseDirection>());
            pose.setRootPose(rootPose);
            Generate(pose.getRootPose(), skeleton.GetRoot());
            poser.setLastPose(pose);

        }
    }

    private void UpdateTextArea()
    {
        //check if the text area
        String CurrentTextAreaValue = poseTextArea.getText();
        if (!(CurrentTextAreaValue.equals(LastTextAreaValue)))
        {

            //make sure that this is a valid pose
            if (CurrentTextAreaValue.length() == 264)
            {
                String subPoseString = "";
                String posePitchString = "";
                int posePitchValue = 0;
                String poseYawString = "";
                int poseYawValue = 0;
                String poseRoleString = "";
                int poseRoleValue = 0;
                int stringPosition = 0;
                //* 1 Right Knee
                subPoseString = CurrentTextAreaValue.substring(stringPosition, stringPosition + 24);
                posePitchString = "0x" + subPoseString.substring(0,8);
                posePitchValue = Integer.decode(posePitchString);
                poseYawString = "0x" + subPoseString.substring(9, 16);
                poseYawValue = Integer.decode(poseYawString);
                poseRoleString = "0x" + subPoseString.substring(17, 24);
                poseRoleValue = Integer.decode(poseRoleString);
                PoseDirection direction = new PoseDirection();
                direction.setPitch(posePitchValue);
                direction.setYaw(poseYawValue);
                direction.setRole(poseRoleValue);
                poseControlMapping.get(skeleton.GetBone("Right Knee")).setPoseDirection(direction);
                //* 2 Right Leg
                stringPosition = 24;
                subPoseString = CurrentTextAreaValue.substring(stringPosition, stringPosition + 24);
                posePitchString = "0x" + subPoseString.substring(0,8);
                posePitchValue = Integer.decode(posePitchString);
                poseYawString = "0x" + subPoseString.substring(9, 16);
                poseYawValue = Integer.decode(poseYawString);
                poseRoleString = "0x" + subPoseString.substring(17, 24);
                poseRoleValue = Integer.decode(poseRoleString);
                direction.setPitch(posePitchValue);
                direction.setYaw(poseYawValue);
                direction.setRole(poseRoleValue);
                poseControlMapping.get(skeleton.GetBone("Right Leg")).setPoseDirection(direction);
                //* 3 Left Knee
                stringPosition = 48;
                subPoseString = CurrentTextAreaValue.substring(stringPosition, stringPosition + 24);
                posePitchString = "0x" + subPoseString.substring(0,8);
                posePitchValue = Integer.decode(posePitchString);
                poseYawString = "0x" + subPoseString.substring(9, 16);
                poseYawValue = Integer.decode(poseYawString);
                poseRoleString = "0x" + subPoseString.substring(17, 24);
                poseRoleValue = Integer.decode(poseRoleString);
                direction.setPitch(posePitchValue);
                direction.setYaw(poseYawValue);
                direction.setRole(poseRoleValue);
                poseControlMapping.get(skeleton.GetBone("Left Knee")).setPoseDirection(direction);
                //* 4 Left Leg
                stringPosition = 72;
                subPoseString = CurrentTextAreaValue.substring(stringPosition, stringPosition + 24);
                posePitchString = "0x" + subPoseString.substring(0,8);
                posePitchValue = Integer.decode(posePitchString);
                poseYawString = "0x" + subPoseString.substring(9, 16);
                poseYawValue = Integer.decode(poseYawString);
                poseRoleString = "0x" + subPoseString.substring(17, 24);
                poseRoleValue = Integer.decode(poseRoleString);
                direction.setPitch(posePitchValue);
                direction.setYaw(poseYawValue);
                direction.setRole(poseRoleValue);
                poseControlMapping.get(skeleton.GetBone("Left Leg")).setPoseDirection(direction);
                //* 5 Left Elbow
                stringPosition = 96;
                subPoseString = CurrentTextAreaValue.substring(stringPosition, stringPosition + 24);
                posePitchString = "0x" + subPoseString.substring(0,8);
                posePitchValue = Integer.decode(posePitchString);
                poseYawString = "0x" + subPoseString.substring(9, 16);
                poseYawValue = Integer.decode(poseYawString);
                poseRoleString = "0x" + subPoseString.substring(17, 24);
                poseRoleValue = Integer.decode(poseRoleString);
                direction.setPitch(posePitchValue);
                direction.setYaw(poseYawValue);
                direction.setRole(poseRoleValue);
                poseControlMapping.get(skeleton.GetBone("Left Elbow")).setPoseDirection(direction);
                //* 6 Left Arm
                stringPosition = 120;
                subPoseString = CurrentTextAreaValue.substring(stringPosition, stringPosition + 24);
                posePitchString = "0x" + subPoseString.substring(0,8);
                posePitchValue = Integer.decode(posePitchString);
                poseYawString = "0x" + subPoseString.substring(9, 16);
                poseYawValue = Integer.decode(poseYawString);
                poseRoleString = "0x" + subPoseString.substring(17, 24);
                poseRoleValue = Integer.decode(poseRoleString);
                direction.setPitch(posePitchValue);
                direction.setYaw(poseYawValue);
                direction.setRole(poseRoleValue);
                poseControlMapping.get(skeleton.GetBone("Left Arm")).setPoseDirection(direction);
                //* 7 Right elbow
                stringPosition = 144;
                subPoseString = CurrentTextAreaValue.substring(stringPosition, stringPosition + 24);
                posePitchString = "0x" + subPoseString.substring(0,8);
                posePitchValue = Integer.decode(posePitchString);
                poseYawString = "0x" + subPoseString.substring(9, 16);
                poseYawValue = Integer.decode(poseYawString);
                poseRoleString = "0x" + subPoseString.substring(17, 24);
                poseRoleValue = Integer.decode(poseRoleString);
                direction.setPitch(posePitchValue);
                direction.setYaw(poseYawValue);
                direction.setRole(poseRoleValue);
                poseControlMapping.get(skeleton.GetBone("Right elbow")).setPoseDirection(direction);
                //* 8 Right arm
                stringPosition = 168;
                subPoseString = CurrentTextAreaValue.substring(stringPosition, stringPosition + 24);
                posePitchString = "0x" + subPoseString.substring(0,8);
                posePitchValue = Integer.decode(posePitchString);
                poseYawString = "0x" + subPoseString.substring(9, 16);
                poseYawValue = Integer.decode(poseYawString);
                poseRoleString = "0x" + subPoseString.substring(17, 24);
                poseRoleValue = Integer.decode(poseRoleString);
                direction.setPitch(posePitchValue);
                direction.setYaw(poseYawValue);
                direction.setRole(poseRoleValue);
                poseControlMapping.get(skeleton.GetBone("Right arm")).setPoseDirection(direction);
                //* 9 Head
                stringPosition = 192;
                subPoseString = CurrentTextAreaValue.substring(stringPosition, stringPosition + 24);
                posePitchString = "0x" + subPoseString.substring(0,8);
                posePitchValue = Integer.decode(posePitchString);
                poseYawString = "0x" + subPoseString.substring(9, 16);
                poseYawValue = Integer.decode(poseYawString);
                poseRoleString = "0x" + subPoseString.substring(17, 24);
                poseRoleValue = Integer.decode(poseRoleString);
                direction.setPitch(posePitchValue);
                direction.setYaw(poseYawValue);
                direction.setRole(poseRoleValue);
                poseControlMapping.get(skeleton.GetBone("Head")).setPoseDirection(direction);
                //* 10 Torso
                stringPosition = 216;
                subPoseString = CurrentTextAreaValue.substring(stringPosition, stringPosition + 24);
                posePitchString = "0x" + subPoseString.substring(0,8);
                posePitchValue = Integer.decode(posePitchString);
                poseYawString = "0x" + subPoseString.substring(9, 16);
                poseYawValue = Integer.decode(poseYawString);
                poseRoleString = "0x" + subPoseString.substring(17, 24);
                poseRoleValue = Integer.decode(poseRoleString);
                direction.setPitch(posePitchValue);
                direction.setYaw(poseYawValue);
                direction.setRole(poseRoleValue);
                poseControlMapping.get(skeleton.GetBone("Torso")).setPoseDirection(direction);
                //* 11 Waist
                stringPosition = 240;
                subPoseString = CurrentTextAreaValue.substring(stringPosition, stringPosition + 24);
                posePitchString = "0x" + subPoseString.substring(0,8);
                posePitchValue = Integer.decode(posePitchString);
                poseYawString = "0x" + subPoseString.substring(9, 16);
                poseYawValue = Integer.decode(poseYawString);
                poseRoleString = "0x" + subPoseString.substring(17, 24);
                poseRoleValue = Integer.decode(poseRoleString);
                direction.setPitch(posePitchValue);
                direction.setYaw(poseYawValue);
                direction.setRole(poseRoleValue);
                poseControlMapping.get(skeleton.GetBone("Waist")).setPoseDirection(direction);
                action.ClickAction();
            }
        }
    }

    public String GenerateOutput()
    {
        StringBuilder value = new StringBuilder(280);
        PoseDirection pose = poseControlMapping.get(skeleton.GetBone("Right Knee")).getPoseDirection();
        value.append(GetFloatValue(pose.getPitch()));
        value.append(GetFloatValue(pose.getYaw()));
        value.append(GetFloatValue(pose.getRole()));
        //value.append('\n');
        
        pose = poseControlMapping.get(skeleton.GetBone("Right Leg")).getPoseDirection();
        value.append(GetFloatValue(pose.getPitch()));
        value.append(GetFloatValue(pose.getYaw()));
        value.append(GetFloatValue(pose.getRole()));
        //value.append('\n');

        pose = poseControlMapping.get(skeleton.GetBone("Left Knee")).getPoseDirection();
        value.append(GetFloatValue(pose.getPitch()));
        value.append(GetFloatValue(pose.getYaw()));
        value.append(GetFloatValue(pose.getRole()));
        //value.append('\n');

        pose = poseControlMapping.get(skeleton.GetBone("Left Leg")).getPoseDirection();
        value.append(GetFloatValue(pose.getPitch()));
        value.append(GetFloatValue(pose.getYaw()));
        value.append(GetFloatValue(pose.getRole()));
        //value.append('\n');

        pose = poseControlMapping.get(skeleton.GetBone("Left Elbow")).getPoseDirection();
        value.append(GetFloatValue(pose.getPitch()));
        value.append(GetFloatValue(pose.getYaw()));
        value.append(GetFloatValue(pose.getRole()));
        //value.append('\n');

        pose = poseControlMapping.get(skeleton.GetBone("Left Arm")).getPoseDirection();
        value.append(GetFloatValue(pose.getPitch()));
        value.append(GetFloatValue(pose.getYaw()));
        value.append(GetFloatValue(pose.getRole()));
       //value.append('\n');

        pose = poseControlMapping.get(skeleton.GetBone("Right Elbow")).getPoseDirection();
        value.append(GetFloatValue(pose.getPitch()));
        value.append(GetFloatValue(pose.getYaw()));
        value.append(GetFloatValue(pose.getRole()));
        //value.append('\n');

        pose = poseControlMapping.get(skeleton.GetBone("Right Arm")).getPoseDirection();
        value.append(GetFloatValue(pose.getPitch()));
        value.append(GetFloatValue(pose.getYaw()));
        value.append(GetFloatValue(pose.getRole()));
        //value.append('\n');

        pose = poseControlMapping.get(skeleton.GetBone("Head")).getPoseDirection();
        value.append(GetFloatValue(pose.getPitch()));
        value.append(GetFloatValue(pose.getYaw()));
        value.append(GetFloatValue(pose.getRole()));
        //value.append('\n');

        pose = poseControlMapping.get(skeleton.GetBone("Torso")).getPoseDirection();
        value.append(GetFloatValue(pose.getPitch()));
        value.append(GetFloatValue(pose.getYaw()));
        value.append(GetFloatValue(pose.getRole()));
        //value.append('\n');

        pose = poseControlMapping.get(skeleton.GetBone("Waist")).getPoseDirection();
        value.append(GetFloatValue(pose.getPitch()));
        value.append(GetFloatValue(pose.getYaw()));
        value.append(GetFloatValue(pose.getRole()));
        //value.append('\n');

        return value.toString();
    }

    private String GetFloatValue(int val)
    {
        String value = Integer.toHexString(val);
        value = value.replace("0x", "");
        value = String.format("%8s", value).replace(' ', '0');
        return value.toUpperCase();
    }

    private void GenerateControls(Bone b)
    {
        if (b.editable)
        {
            PoseControl tempcontrol = new PoseControl(b.Name);
            tempcontrol.addPoseAction(action);
            poseControlMapping.put(b, tempcontrol);
            poseControls.add(tempcontrol);
        }
        if (b.childBones != null)
        {
            for (int cb = 0; cb < b.childBones.size(); cb++)
            {
                GenerateControls(b.childBones.get(cb));
            }
        }
    }

    /* output format
     *
     * 1 Right Knee
     * 2 Right Leg
     * 3 Left Knee
     * 4 Left Leg
     * 5 Left Elbow
     * 6 Left Arm
     * 7 Gight elbow
     * 8 Right arm
     * 9 Head
     * 10 Torso
     * 11 Waist
     *
     */

}
